/**
 * Author: Dmitry Ustimov
 * Date: 5/22/13
 * Time: 2:17 PM
 */

package com.gmail.dmitryustimov.ms.java7.visitor.mod_actionmap.work.demo.structure1_16_4096_1048576;

import com.gmail.dmitryustimov.ms.java7.patternslib.visitor.actionmap.VisitAction;
import java.util.HashMap;
import java.util.Map;

public class ConcreteElementVisitor<T> extends ElementVisitor<T> {

    public <S extends T> ConcreteElementVisitor() {
        Map<Class<? extends T>, VisitAction<? extends T>> actions = new HashMap<>();
        actions.put((Class<S>)ElementRoot.class, (VisitAction<S>)this.new ElementRootVisitor());
        actions.put((Class<S>)ElementA.class,    (VisitAction<S>)this.new ElementAVisitor());
        actions.put((Class<S>)ElementB.class,    (VisitAction<S>)this.new ElementBVisitor());
        actions.put((Class<S>)ElementC.class,    (VisitAction<S>)this.new ElementCVisitor());
        init(actions);
    }

    private void printElement(Element element) {
    }

    public class ElementRootVisitor implements VisitAction<ElementRoot> {
        @Override
        public void visit(ElementRoot element) {
            printElement(element);
            visitElements(element, ConcreteElementVisitor.this);
        }
    }

    public class ElementAVisitor implements VisitAction<ElementA> {
        @Override
        public void visit(ElementA element) {
            printElement(element);
            visitElements(element, ConcreteElementVisitor.this);
        }
    }

    public class ElementBVisitor implements VisitAction<ElementB> {
        @Override
        public void visit(ElementB element) {
            printElement(element);
            visitElements(element, ConcreteElementVisitor.this);
        }
    }

    public class ElementCVisitor implements VisitAction<ElementC> {
        @Override
        public void visit(ElementC element) {
            printElement(element);
            visitElements(element, ConcreteElementVisitor.this);
        }
    }
}
